﻿using CrawlerApp.Core.Entities;
using CrawlerApp.Infrastructure.Interfaces;
using CrawlerApp.Services.Interfaces;
using Microsoft.Extensions.Configuration;
using Quartz;
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace CrawlerApp.Services.Job
{
    public class CategoryJob : IJob
    {
        private readonly ILogger logger;
        private readonly IConfiguration configuration;
        private readonly IRepository<Category> repository;
        private readonly IHtmlPraseService htmlPrase;
        const string url = "http://www.zxcs.me/map.html";

        public static event EventHandler SuccessHandler;
        public static event EventHandler FailedHandler;

        public CategoryJob(ILogger logger, IConfiguration configuration, IRepository<Category> repository, IHtmlPraseService htmlPrase)
        {
            this.logger = logger;
            this.configuration = configuration;
            this.repository = repository;
            this.htmlPrase = htmlPrase;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            logger.Information("开始采集分类信息。");

            var categories = await htmlPrase.GetSpecifyCollectionAsync(url, "//div[@id='sort']/ul/li/a", selector => new Category(selector.InnerText, selector.Attributes["href"].Value), it => !string.IsNullOrWhiteSpace(it.InnerText));

            try
            {
                var dbCategorys = await repository.ToListAsync(onChange: true);

                foreach(var category in categories)
                {
                    if (dbCategorys.Any(c => c.Name == category.Name))
                    {
                        //var newCategory = dbCategorys.SingleOrDefault(c => c.Href != category.Href || c.Total != category.Total);
                        //if(newCategory != null)
                        //{
                        //    newCategory.SetHref(category.Href).SetLength(category.Total);
                        //    await repository.UpdateAsync(newCategory);
                        //}
                    }
                    else
                    {
                        await repository.AddAsync(category);
                    }
                }
                SuccessHandler?.Invoke(this, null);
            }
            catch(Exception ex)
            {
                logger.Error(ex, ex.Message);
                FailedHandler?.Invoke(this, null);
            }


            //await new BrowserFetcher(new BrowserFetcherOptions { Host = "https://mirrors.huaweicloud.com" }).DownloadAsync(BrowserFetcher.DefaultRevision);

            //using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }))
            //{
            //    using (var page = await browser.NewPageAsync())
            //    {
            //        try
            //        {
            //            await page.GoToAsync(url);
            //            var jsSelector = @"Array.from(document.querySelectorAll('#sort li a')).map(a=>{return {name:a.text,href:a.href}})";
            //            var categorys = await page.EvaluateExpressionAsync<IReadOnlyCollection<Category>>(jsSelector);

            //            var dbCategorys = await repository.ToListAsync();

            //            foreach (var category in categorys.Where(c => !string.IsNullOrWhiteSpace(c.Name)))
            //            {
            //                // 添加
            //                if (!dbCategorys.Any(c => c.Name == category.Name))
            //                {
            //                    await repository.AddAsync(category);
            //                }
            //                else
            //                {
            //                    var dbCategory = dbCategorys.SingleOrDefault(c => c.Name == category.Name && (c.Length != category.Length || c.Href != category.Href));
            //                    if (dbCategory != null) // 更新
            //                    {
            //                        dbCategory
            //                            .SetLength(category.Length)
            //                            .SetHref(category.Href);
            //                        await repository.UpdateAsync(dbCategory);
            //                    }
            //                }
            //            }
            //            SuccessHandler?.Invoke(this, null);
            //        }
            //        catch(PuppeteerException ex)
            //        {
            //            logger.Error(ex, ex.Message);
            //            FailedHandler?.Invoke(this, null);
            //        }
            //    }
            //}

            logger.Information("分类信息采集结束。");
        }
    }
}
